<template>
  <div :class='$style.wrap'>
    <div :class='$style.tip'>
      <div :class='$style.similar' :style='{width: (100 -coverPrecent ) + "%"}'>相似区间</div>
      <div :class='$style.mid'></div>
      <div :class='$style.future' :style='{width : coverPrecent + "%"}'>模拟走势</div>
    </div>
    <div :class='$style.loading' v-if='loading.status.length > 0' @click='fetchData'>
      <img v-if='!loading.isLoading' src="~assets/images/error_2x.png">
      <div v-html='loading.status'></div>
    </div>
    <!-- <k-line v-if='templateStock != null'
      :class='$style.chart'
      :coverPrecent='coverPrecent'
      coverText='后续走势如何?'
      :stock='templateStock'></k-line> -->
    <transition
      :enter-class='$style.fadeEnter'
      :enter-active-class='$style.fadeEnterActive'
      :leave-active-class='$style.fadeLeaveActive'>
      <div v-if="similarStock">
        <main-stock
          page='index'
          :isShare='isShare'
          :guessed='guessed'
          :mainStock='templateStock'
          :stock='filterMarketCode(contrast.MARKET_CODE) + contrast.STOCK_CODE'></main-stock>
        <!-- <k-line v-if='similarStock != null'
          :coverPrecent='coverPrecent'
          :stock='similarStock'
          ></k-line> -->
        <similar-item :similarStock="similarStock"></similar-item>
      </div>
    </transition>
  </div>
</template>

<script>
  import kLine from './kLine'
  import MainStock from '@/components/stock/MainStock'
  import SimilarItem from '@/components/todaySimilar/SimilarItem'
  import RemoteDAO from '@/common/RemoteDAO'
  import jsonSKLine from '@/filters/jsonSKLine'
  import Constant from '@/common/constant'
  import CommonUtil from '@/common/common.util'
  export default {
    components: { MainStock, kLine, SimilarItem },
    filters: { jsonSKLine },
    props: {
      isShare: Boolean,
      contrast: {
        type: Object,
        default: function () {
          return {
            RANK: 0,
            STOCK_CODE: '', // 模板股票代码
            MARKET_CODE: '', // 模板股票的市场代码
            STOCK_NAME: '', // 模板股票名称
            TOP_SIMILARITYL: '', // 最相似股票的相似度
            TOP_STOCK_CODE: '', // 最相似股票代码
            TOP_MARKET_COD: '', // 最相似股票的市场代码
            TOP_STOCK_NAME: '', // 最相似股票名称
            PRICE_CHG_3DAYS: '', // 后三个交易日涨跌幅
            RECOMM_TYPE: '', // 推荐类型
            templateStock: null,
            similarStock: null
          }
        }
      }
    },
    data () {
      return {
        args: {
          dateNum: 30,
          postDateNum: 30
        },
        coverPrecent: 50,
        templateStock: { // 模板股票
          stockName: '',
          kData: [],
          lineData: [],
          timeData1: [],
          timeData2: ['', ''],
          max: 100,
          min: 0
        },
        patClosePriceLast: 0, // 模板股票最后一天收盘价
        simiList: [],
        guessed: false,
        similarStock: null, // 相似股票
        loading: {
          isLoading: false,
          status: ''
        }
      }
    },
    mounted () {
      this.coverPrecent = parseInt(this.args.postDateNum / (this.args.dateNum + this.args.postDateNum) * 100)
      this.fetchData()
    },
    methods: {
      filterMarketCode (marketCode) {
        switch (marketCode) {
          case '1':
            return 'SH'
          case '2':
            return 'SZ'
          default:
            return 'SH'
        }
      },
      fetchData () {
        if (this.loading.isLoading) return
        this.loading.isLoading = true
        this.loading.status = '加载中...'
        if (this.isShare) {
          this.fetchDataFromURL()
        } else {
          var localData = this.fetchDataFromLocalStorage()
          if (!localData) this.fetchDataFromApp()
          else {
            setTimeout(() => {
              this.templateStock = localData.templateStock
              this.similarStock = localData.similarStock
              this.guessed = true
            }, 0)
          }
        }
      },
      fetchDataFromLocalStorage () {
        var xskxTodaySimilar = JSON.parse(localStorage.getItem(Constant.IndexPageName)) || {stocks: []}
        if (!xskxTodaySimilar.time) return null
        else {
          let time = new Date(xskxTodaySimilar.time)
          let today = new Date()
          if (!(time.getFullYear() === today.getFullYear() && time.getMonth() === today.getMonth() && time.getDate() === today.getDate())) return null // 不是同一天
        }
        var result = null
        for (let i = 0; i < xskxTodaySimilar.stocks.length; i++) {
          if (xskxTodaySimilar.stocks[i].STOCK_CODE === this.contrast.STOCK_CODE) {
            result = xskxTodaySimilar.stocks[i]
            break
          }
        }
        if (result != null && result.templateStock && result.templateStock.lineData && result.templateStock.lineData.length > 0) return result
        return null
      },
      fetchDataFromURL () {
        if (this.contrast.templateStock && this.contrast.similarStock) {
          this.templateStock = this.contrast.templateStock
          this.similarStock = this.contrast.similarStock
          this.loading.isLoading = false
          this.loading.status = ''
        } else {
          this.loading.status = '数据跑到 <a href="https://yyz.gtja.com/dl/" >国泰君安君弘APP</a> 去啦>_<'
          this.loading.isLoading = false
        }
      },
      fetchDataFromApp () {
        var args = {
          stockCode: this.contrast.STOCK_CODE,
          marketCode: this.contrast.MARKET_CODE,
          dateNum: this.args.dateNum,
          threshold: '',
          reqNum: 10,
          preDateNum: 0,
          postDateNum: this.args.postDateNum
        }
        RemoteDAO.callUC12005211(args).then(resp => {
          if (resp.data.body.length < 2) {
            this.loading.status = '出错了，点击重试'
            this.loading.isLoading = false
            return
          }
          resp.data.body = jsonSKLine(resp.data.body)
          this.formatTemplateStock(resp.data.body)
          // this.similarStock = resp.data.body[1].K_LINE_JSON_CONTENT
          this.getMaxMin()
          this.loading.isLoading = false
          this.loading.status = ''
          this.updateShareData()
        }, reject => {
          this.loading.status = '出错了，点击重试'
          this.loading.isLoading = false
        })
      },
      formatTemplateStock (data) {
        var templateStock = {
          stockName: '',
          stockCode: '',
          kData: [],
          lineData: [],
          timeData1: [],
          timeData2: ['', ''],
          max: 100,
          min: 0
        }
        for (let list of data) {
          let listData = list.K_LINE_JSON_CONTENT
          if (Number(listData.SIMI_RANK) === 0) {
            listData.K_LIST.forEach((item, index) => {
              if (item.OPEN_PRICE === item.CLOSE_PRICE && index > 0) { // 处理：开盘收盘相等，但比前一个交易日价高仍显示绿色的情况
                if (item.CLOSE_PRICE >= listData.K_LIST[index - 1].CLOSE_PRICE) {
                  item.CLOSE_PRICE = item.CLOSE_PRICE + 0.000001
                }
              }
              if (item.DATE_TYPE === 'PAT') {
                templateStock.kData.push([item.OPEN_PRICE, item.CLOSE_PRICE, item.MIN_PRICE, item.MAX_PRICE])
                templateStock.timeData1.push(CommonUtil.formatDateSlash(item.TRADEDATE))
              }
            })
            templateStock.stockName = listData.STOCK_NAME_PAT
            templateStock.stockCode = listData.STOCK_CODE_PAT
            this.templateStock = templateStock
            this.patClosePriceLast = templateStock.kData[templateStock.kData.length - 1][1]
          }
          // 处理出相似股票的配置列表
          if (Number(listData.SIMI_RANK) > 0) {
            let simiStock = {
              priceChgs: [],
              kData1: [],
              kData2: [],
              timeData1: [],
              timeData2: [],
              max: 100,
              min: 0
            }
            listData.K_LIST.forEach(function (item, index) {
              if (item.OPEN_PRICE === item.CLOSE_PRICE && index > 0) { // 处理：开盘收盘相等，但比前一个交易日价高仍显示绿色的情况
                if (item.CLOSE_PRICE >= listData.K_LIST[index - 1].CLOSE_PRICE) {
                  item.CLOSE_PRICE = item.CLOSE_PRICE + 0.000001
                }
              }
              if (item.DATE_TYPE === 'PAT') {
                simiStock.kData1.push([item.OPEN_PRICE, item.CLOSE_PRICE, item.MIN_PRICE, item.MAX_PRICE])
                simiStock.timeData1.push(CommonUtil.formatDateSlash(item.TRADEDATE))
              } else if (item.DATE_TYPE === 'POST') {
                simiStock.kData2.push([item.OPEN_PRICE, item.CLOSE_PRICE, item.MIN_PRICE, item.MAX_PRICE])
                simiStock.timeData2.push(CommonUtil.formatDateSlash(item.TRADEDATE))
                simiStock.priceChgs.push(item.PRICE_CHG)
              }
            })
            let nums = CommonUtil.compute(simiStock.kData1.concat(simiStock.kData2))
            simiStock.max = nums.max
            simiStock.min = nums.min
            simiStock.stockName = listData.STOCK_NAME
            simiStock.stockCode = listData.STOCK_CODE
            simiStock.market = CommonUtil.getMarketName(listData.MARKET_CODE)
            simiStock.marketCode = listData.MARKET_CODE
            simiStock.similarity = CommonUtil.toFixed(listData.SIMILARITY * 100, 2)
            this.simiList.push(simiStock)
          }
        }
        this.similarStock = this.simiList[0]
        var arr = []
        for (let stock of this.simiList) {
          arr.push(stock.priceChgs)
        }
        this.getTrend(arr, this.patClosePriceLast) // 获取后续走势
        this.getMaxMin()
        this.guessed = true
      },
      getTrend (arr, closePrice) {
        let patClosePrices = [] // 模板股票后续30天每天的预测收盘价
        let priceChgMs = [] // 模板股票后续30天每天的预测涨幅值
        // 行列置换(考虑到第二维数组的长度不一样的情况）
        let newArr = Array(Math.max.apply({}, arr.map(e => e.length)))
        for (let i = 0; i < newArr.length; i++) {
          newArr[i] = ''
        }
        let columnArr = newArr.map((_e, outerIndex) => arr.map((e, innerIndex) => e[outerIndex]).filter(ele => ele !== undefined))
        // console.log('columnArr:', columnArr)

        // 计算arr每列的平均数
        for (let column of columnArr) {
          let avg = column.reduce((total, num) => { return total + num }) / column.length
          priceChgMs.push(avg)
        }
        // console.log('priceChgMs:', priceChgMs)

        // 计算模板股票后续30天预测的每天收盘价
        for (let priceChgM of priceChgMs) {
          closePrice = closePrice * (priceChgM + 1)
          patClosePrices.push(closePrice)
          this.templateStock.timeData2.unshift('')
        }
        // console.log('patClosePrices:', patClosePrices)

        this.templateStock.lineData = patClosePrices
        let nums = CommonUtil.compute(this.templateStock.kData.concat(this.templateStock.lineData))
        this.templateStock.max = nums.max + 1
        this.templateStock.min = nums.min
      },
      getMaxMin () {
        let n = CommonUtil.compute(this.templateStock.kData) // 模板股票3相似区间的最高值和最低值
        let h = n.max - n.min // 模板股票相似区间 + 后续趋势 k线容器高度
        let tbr = (this.templateStock.max - n.max) / h // 模板股票相似区间上方空档高度，与K线高度 比值 top-blank-rate
        let bbr = (n.min - this.templateStock.min) / h // 模板股票相似区间下方空档高度，与K线高度 比值  bottom-blank-rate

        for (let simiStock of this.simiList) {
          let num = CommonUtil.compute(simiStock.kData1) // 模板股票30内数据
          let height = num.max - num.min // 相似股票相似区间 + 后续区间 数据最高离最低距离
          let tbrEmp = (simiStock.max - num.max) / height // 相似股票相似区间上方空档高度，与K线高度 比值 top-blank-rate
          let bbrEmp = (num.min - simiStock.min) / height // 相似股票相似区间下方空档高度，与K线高度 比值  bottom-blank-rate
          if (tbrEmp > tbr) {
            tbr = tbrEmp
          }
          if (bbrEmp > bbr) {
            bbr = bbrEmp
          }
        }

        for (let simiStock of this.simiList) {
          let num = CommonUtil.compute(simiStock.kData1) // 模板股票30内数据
          let height = num.max - num.min // 模板股票30内K线数据最高离最低距离
          simiStock.max = num.max + height * tbr
          simiStock.min = num.min - height * bbr
        }

        this.templateStock.max = n.max + h * tbr
        this.templateStock.min = n.min - h * bbr
      },
      updateShareData () {
        var xskxTodaySimilar = JSON.parse(localStorage.getItem(Constant.IndexPageName) || '{"stocks": []}')
        if (xskxTodaySimilar == null) return
        xskxTodaySimilar.stocks[parseInt(this.contrast.RANK) - 1].templateStock = this.templateStock
        xskxTodaySimilar.stocks[parseInt(this.contrast.RANK) - 1].similarStock = this.similarStock
        xskxTodaySimilar.time = new Date().getTime()
        localStorage.setItem(Constant.IndexPageName, JSON.stringify(xskxTodaySimilar))
      }
    }
  }
</script>

<style lang="less" module>
  .wrap{
    background: #f8f8f8;
    padding-bottom: 14px;
    position: relative;
    min-height: 574px;
    .tip{
      height: 60px;
      display: flex;
      width: 100%;
      .similar{
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: #f6f6f6;
        font-size: 28px;
        color: #999;
        // box-shadow: 0 15px 10px -8px #ddd inset;
      }
      .mid{
        height: 60%;
        border-left: 1px solid #eaeaea;
        margin: auto 0;
      }
      .future{
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: #f6f6f6;
        font-size: 28px;
        color: #999;
        // box-shadow: 0 15px 10px -8px #ddd inset, -4px 0px 2px 0px #ddd;
      }
    }
    .loading{
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      text-align: center;
      // line-height: 400px;
      position: absolute;
      color: #ccc;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      img{
        width: 130px;
      }
    }
    .chart{
      margin-bottom: 10px;
    }
  }
  .fadeEnterActive, .fadeLeaveActive {
    transition: opacity .5s
  }
  .fadeEnter, .fadeLeaveTo /* .fade-leave-active in below version 2.1.8 */ {
    opacity: 0
  }
</style>
